package com.lagou.factory;

import com.lagou.utils.TransactionManager;
import org.assertj.core.internal.cglib.proxy.Enhancer;
import org.assertj.core.internal.cglib.proxy.MethodInterceptor;

import java.lang.reflect.Method;
import java.util.List;

/**
 * desc: cglib 代理类
 *
 * @author tengfei wang
 * @version 1.0
 * @date Created in 7/9/2020
 */
public class CglibProxy implements AopProxy {

    @Override
    public Object createProxy(Object o) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(o.getClass());
        enhancer.setCallback((MethodInterceptor) (o1, method, objects, methodProxy) -> {
            System.out.println("cglib start");
            Object invoke = method.invoke(o, objects);
            System.out.println("cglib end");
            return invoke;
        });
        return enhancer.create();
    }

    @Override
    public Object createProxyWithTransaction(Object o, List<Method> methods) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(o.getClass());
        enhancer.setCallback((MethodInterceptor) (o1, method, objects, methodProxy) -> {
            Object invoke;
            boolean anyMatch = methods.stream().anyMatch(w -> w.getName().equals(method.getName()));
            if (anyMatch) {
                TransactionManager.getInstance().beginTransaction();
                try {
                    invoke = method.invoke(o, objects);
                    TransactionManager.getInstance().commit();
                } catch (Exception e) {
                    TransactionManager.getInstance().rollback();
                    throw e;
                }
                return invoke;
            }
            invoke = method.invoke(o, objects);
            return invoke;
        });
        return enhancer.create();
    }

}
